package com.atguigu.tingshu.common.config.threadpool;

import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * Description:
 *
 * @author Yanxinhao on 2025/1/24
 */
@Configuration
@EnableConfigurationProperties(ThreadPoolProperties.class)
public class ThreadPoolConfiguration {

    Logger logger = LoggerFactory.getLogger(ThreadPoolConfiguration.class);

    @Autowired
    private ThreadPoolProperties properties;

    @Value("${spring.application.name}")
    private String appName;

    @Value("${server.port}")
    private String port;

    @Bean
    public ThreadPoolExecutor threadPoolExecutor(){


        //线程池工厂
        ThreadFactory threadFactory = new ThreadFactory(){
            AtomicInteger atomicInteger = new AtomicInteger(0);
            @Override
            public Thread newThread(@NotNull Runnable r) {
                Thread thread = new Thread(r);
                thread.setName("thread-pool-" + appName + "-" + port + "-" + atomicInteger.incrementAndGet());
                return thread;
            }
        };

        //自定义拒绝策略
        RejectedExecutionHandler rejectedExecutionHandler = new RejectedExecutionHandler(){
            @Override
            public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
                logger.error("提交任务：{}被自定义的拒绝策略收到", r);
                throw new RejectedExecutionException("Task " + r.toString() +
                        " rejected from " +
                        executor.toString());
            }
        };


        /**
         * 线程池七大参数
         * 1.核心线程数
         * 2.最大线程数
         * 3.非核心线程的存活时间
         * 4.时间单位
         * 5.阻塞队列
         * 6.线程池工厂
         * 7.拒绝策略
         */
        return new ThreadPoolExecutor(
                properties.getCorePoolSize(), //核心线程数
                properties.getMaximumPoolSize(), //最大线程数
                properties.getKeepAliveTime(), //非核心线程的存活时间
                properties.getTimeUnit(), //时间单位
                new LinkedBlockingDeque<>(properties.getBlockingQueueSize()), //阻塞队列
                threadFactory,//线程工厂
                rejectedExecutionHandler//拒绝策略
        );
    }
}